package channelScheduler

import (
	"fmt"
	"gitee.com/fierce_wolf/go-fox-edge-channel-common/channelAPI"
	"gitee.com/fierce_wolf/go-fox-edge-channel-common/channelStatus"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntityManager"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEnv"
	"gitee.com/fierce_wolf/go-fox-edge-common/commLogger"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisService"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Differ"
	"time"
)

type channelManageScheduler struct {
	updateTime       int64
	channelEntityMap map[string]*commEntity.ChannelEntity
}

// Scheduler 创建一个线程
func (e *channelManageScheduler) Scheduler() {
	go e.scheduler()
}

// 线程函数
func (e *channelManageScheduler) scheduler() {
	for true {
		time.Sleep(1 * time.Second)
		if !commEntityManager.EntityManager.Initialized {
			continue
		}

		// 检测：是否实例化接口
		if channelAPI.Service.OpenChannel == nil || channelAPI.Service.CloseChannel == nil {
			continue
		}

		// 检测：数据是否更新
		updateTime := commRedisService.GetUpdateTime(commEntity.Type.ChannelEntity.Type())
		if e.updateTime == updateTime {
			continue
		}
		e.updateTime = updateTime

		// 获得全体ChannelEntity
		entityList, err := commRedisService.GetEntityMap(commEntity.Type.ChannelEntity.Type())
		if err != nil {
			continue
		}

		// 处理数据
		channelType := commEnv.Service.ModelName
		channelMap := make(map[string]*commEntity.ChannelEntity)
		for _, entity := range entityList {
			channelEntity := entity.(*commEntity.ChannelEntity)
			if channelEntity.ChannelType != channelType {
				continue
			}

			channelMap[channelEntity.ChannelName] = channelEntity
		}

		// 比较差异
		addList := make(map[string]interface{})
		delList := make(map[string]interface{})
		Differ.Set.DifferByKey(e.channelEntityMap, channelMap, &addList, &delList)

		for key := range addList {
			// 打开通道的南向
			channelEntity := channelMap[key]
			err := channelAPI.Service.OpenChannel.OpenChannel(channelEntity.ChannelName, channelEntity.ChannelParam)
			if err != nil {
				message := fmt.Sprintf("通道打开失败:%v: %v", channelEntity.ChannelName, err)
				commLogger.Error(message)

				channelStatus.UpdateOpenStatus(key, true)
			} else {
				e.channelEntityMap[key] = channelEntity

				message := fmt.Sprintf("通道打开成功:%v", channelEntity.ChannelName)
				commLogger.Info(message)

				channelStatus.UpdateOpenStatus(key, false)
			}
		}

		for key := range delList {
			// 打开通道的南向
			channelEntity := e.channelEntityMap[key]
			err := channelAPI.Service.CloseChannel.CloseChannel(channelEntity.ChannelName, channelEntity.ChannelParam)
			if err != nil {
				message := fmt.Sprintf("通道关闭失败:%v: %v", channelEntity.ChannelName, err)
				commLogger.Error(message)
			} else {
				delete(e.channelEntityMap, key)

				message := fmt.Sprintf("通道关闭成功:%v", channelEntity.ChannelName)
				commLogger.Error(message)

				channelStatus.UpdateOpenStatus(key, false)
			}

		}
	}
}

func (e *channelManageScheduler) openChannel(channelEntity *commEntity.ChannelEntity) {
	// 定义一个最终的异常拦截，用来防止可能的代码BUG
	defer func() {
		if r := recover(); r != nil {
			message := fmt.Sprintf("通道打开失败:%v: %v", channelEntity.ChannelName, r)
			commLogger.Error(message)
		}
	}()

	// 打开通道的南向
	channelAPI.Service.OpenChannel.OpenChannel(channelEntity.ChannelName, channelEntity.ChannelParam)
	e.channelEntityMap[channelEntity.ChannelName] = channelEntity
}

func (e *channelManageScheduler) closeChannel(channelEntity *commEntity.ChannelEntity) {
	// 定义一个最终的异常拦截，用来防止可能的代码BUG
	defer func() {
		if r := recover(); r != nil {
			message := fmt.Sprintf("通道关闭失败:%v: %v", channelEntity.ChannelName, r)
			commLogger.Error(message)
		}
	}()

	// 打开通道的南向
	channelAPI.Service.CloseChannel.CloseChannel(channelEntity.ChannelName, channelEntity.ChannelParam)
	delete(e.channelEntityMap, channelEntity.ChannelName)
}
